home account info subscribe login search FAQ/help site map contact us


 
Brief Full
 Advanced
      Search
 Search Tips
To access the contents, click the chapter and section titles.

Bug Proofing Visual Basic: A Guide to Error Handling and Prevention
(Publisher: John Wiley & Sons, Inc.)
Author(s): Rod Stephens
ISBN: 0471323519
Publication Date: 11/01/98

Search this book:
 
Previous Table of Contents Next


This is an even bigger problem if the routine declares other variables far from its beginning, a practice I do not recommend. For example, in the following code the variables i and j are both static.

Static Private Sub MyStaticRoutine()
Dim i As Integer
        :
    ‘ Lots of code.
        :
    Dim j As Integer
        :
End Sub

In cases like this, the static keyword may not be visible on the screen so the reader may assume incorrectly that j is not static.

Make static variables obvious by declaring them static individually.

Use Private and Public

Within a subroutine, the Dim statement declares a variable with scope limited to that routine. At the module level, the Dim statement declares a variable with scope limited to that module.

However, scope is somewhat inconsistent if you do not use Private or Public when you declare variables and routines. Variables declared with Dim are private to the module. Subroutines, functions, and property procedures declared with neither Private nor Public are public and available outside the module.

To make the code obvious, always use Private and Public instead of Dim when you declare symbols at the module level. This includes routines, variables, constants, types, and enumerated values. Using Private and Public makes a symbol’s scope obvious.

‘ This type is defined only within the module.
Private Type PrivateType
    :
End Type

‘ This type is defined within the whole program.
Public Type PublicType
    :
End Type

‘ This variable is defined only within the module.
Private PrivateVariable As Integer

‘ This variable is defined within the whole program.
Public PublicVariable As Integer

‘ This subroutine is defined only within the module.
Private Sub PrivateSub()
    :
End Sub

‘ This function is defined within the whole program.
Public Function PublicFunction() As Integer
    :
End Sub

Using Private and Public makes a symbol’s scope obvious.

Use ByVal and ByRef

When you declare a routine’s parameter with the ByVal (by value) keyword, any changes the routine makes will not be returned to the calling routine. The routine works with a separate copy of the parameter so changes are lost when the routine ends.

When you declare a routine’s parameter with the ByRef (by reference) keyword, any changes the routine makes are returned to the calling routine. The routine uses the same copy of the variable as the caller so any changes it makes are permanent.

If you declare a parameter with neither ByVal nor ByRef, Visual Basic passes the value by reference. Not only is this not obvious, it is also usually the wrong option. Passing an argument ByVal protects the calling routine from accidental changes to the parameter. To make the caller as safe as possible, every parameter should be passed by value unless part of the routine’s purpose is to explicitly change the value of the parameter.

Use ByVal whenever possible. Use ByRef to emphasize the fact that a parameter may be changed by the routine. This makes it obvious that the value may change, and it makes it obvious that you did not simply forget to declare the parameter ByVal.

The following code declares a subroutine that modifies its second parameter but not its first.

Private Sub MyRoutine(ByVal num_employees As Integer, _
    ByRef num_jobs As Integer)
        :

Note that arrays must always be passed ByRef. Visual Basic does this for efficiency reasons. When you pass a parameter ByVal, Visual Basic makes a separate copy of the value for the routine to manipulate. Copying a large array can take a long time, so Visual Basic passes it by reference instead of by value.

If you do not intend to modify the entries in an array parameter, you can leave the ByRef off to hint that you do not intend to change the values. Visual Basic will not stop the routine from changing them, however.

‘ Print a list of employees without modifying the list.
Private Sub PrintEmployees(employees() As String)
    :

One confusing case still occurs when the calling routine passes a value that cannot be modified as a ByRef parameter; for example, if the calling routine uses the value 10 as in the following code. The called routine cannot really modify the value 10 and return the modified result to the calling routine since the value is not stored in a variable.

    SetTemperature 10, 20
        :
‘ Change the temperature. Return the previous temperature
‘through the temperature parameter.
Private Sub SetTemperature(ByRef temperature As Integer, _
    ByVal duration As Integer)
        :

In this situation, Visual Basic creates a temporary variable and places the value 10 in it. Even if the routine modifies the temporary variable, the calling routine will not see the effect.

This is a reasonable course for Visual Basic to take, but it may indicate a bug in the calling routine. The called routine changes its parameter for a reason. Ignoring the change indicates a possible mistake by the caller.

Try not to pass unchangeable values into routines as ByRef parameters. Visual Basic will not warn you if you do, but this may cause a misunderstanding.

Use Line Continuation

If a line gets too long, it may not be obvious that some of it extends beyond the edge of the window. This can be very confusing. Even after the reader realizes there is more to the command, he must scroll the code window back and forth to read the entire statement. The added distraction makes it harder to understand the code. It also prevents the reader from seeing all of the adjacent lines at the same time.

Use line continuation characters to make each line completely visible. Use indentation to show that the subsequent lines are part of the same statement. Unless your project standardizes on a certain size monitor and everyone works with maximized code windows, you should assume the code window is relatively small.

Break lines soon enough that the line continuation characters are visible. If that character is hidden, the statement may look like two separate commands. Proper indentation can warn the reader that something unusual is happening, but the reader may still become confused.

Break long single-line If statements before the Then keyword. This makes it more obvious that the next line is part of the If statement. For example, consider the following statement:

If num_processed < num_employees Then _
    ProcessEmployee

Now suppose another programmer wants to add a new statement that keeps the user posted about the program’s progress. If the programmer does not notice the line continuation character, he might make the change like this:

If num_processed < num_employees Then _
    ProcessEmployee
    UpdateStatusBar

At a quick glance, this looks correct, but the new UpdateStatusBar command is not contained within the If statement. The scope of the If statement is obvious if the original code is broken before the Then keyword like this:

If num_processed < num_employees _
    Then ProcessEmployee

Even if the reader does mistakenly add a new line thinking it will lie within the If statement, the result looks suspicious. It is easier to notice that there is a mistake in the following code than it is in the previous incorrect version.

If num_processed < num_employees _
    Then ProcessEmployee
    UpdateStatusBar

An even better solution is to make long If statements use multiple lines. The difference in performance is tiny and the code is much more obvious.

If num_processed < num_employees Then
    ProcessEmployee
    UpdateStatusBar
End If


Previous Table of Contents Next


Products |  Contact Us |  About Us |  Privacy  |  Ad Info  |  Home

Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written permision of EarthWeb is prohibited.